<template>
  <div class="similarity-cluster-view">
    <!-- 视图控制 -->
    <div class="view-controls mb-6 p-4 bg-white rounded-lg border border-gray-200">
      <div class="flex items-center justify-between">
        <div class="flex items-center gap-4">
          <h3 class="text-lg font-semibold text-gray-900">相似度聚类视图</h3>
          <div class="flex items-center gap-2">
            <span class="text-sm text-gray-600">显示模式:</span>
            <button 
              @click="viewMode = 'clusters'"
              :class="[
                'px-3 py-1.5 text-sm rounded-lg transition-colors',
                viewMode === 'clusters' 
                  ? 'bg-blue-500 text-white' 
                  : 'bg-gray-200 text-gray-700 hover:bg-gray-300'
              ]"
            >
              聚类
            </button>
            <button 
              @click="viewMode = 'heatmap'"
              :class="[
                'px-3 py-1.5 text-sm rounded-lg transition-colors',
                viewMode === 'heatmap' 
                  ? 'bg-blue-500 text-white' 
                  : 'bg-gray-200 text-gray-700 hover:bg-gray-300'
              ]"
            >
              相似度矩阵
            </button>
          </div>
        </div>
        
        <div class="flex items-center gap-4">
          <!-- 相似度阈值控制 -->
          <div class="flex items-center gap-2">
            <span class="text-sm text-gray-600">相似度阈值:</span>
            <input 
              type="range" 
              v-model="similarityThreshold"
              min="0"
              max="1"
              step="0.05"
              class="w-24"
            />
            <span class="text-sm font-medium text-gray-700 min-w-[3rem]">
              {{ Math.round(similarityThreshold * 100) }}%
            </span>
          </div>
          
          <!-- 刷新聚类 -->
          <button 
            @click="refreshClusters"
            :disabled="isLoading"
            class="px-3 py-1.5 bg-green-500 hover:bg-green-600 text-white text-sm rounded-lg transition-colors disabled:opacity-50"
          >
            <svg v-if="isLoading" class="w-4 h-4 animate-spin mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path>
            </svg>
            重新聚类
          </button>
        </div>
      </div>
    </div>

    <!-- 聚类视图 -->
    <div v-if="viewMode === 'clusters'" class="clusters-container">
      <div class="grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-6">
        <div 
          v-for="cluster in filteredClusters" 
          :key="cluster.id"
          class="cluster-card bg-white rounded-lg border border-gray-200 shadow-sm overflow-hidden"
        >
          <!-- 聚类头部 -->
          <div 
            class="cluster-header p-4 bg-gradient-to-r from-blue-50 to-purple-50 border-b border-gray-200 cursor-pointer"
            @click="toggleClusterExpansion(cluster.id)"
          >
            <div class="flex items-center justify-between">
              <div class="flex items-center gap-3">
                <div class="w-3 h-3 rounded-full" :style="{ backgroundColor: getClusterColor(cluster.similarity_score) }"></div>
                <h4 class="font-semibold text-gray-900">聚类 {{ cluster.id.split('_')[1] }}</h4>
                <span class="px-2 py-1 bg-white text-xs rounded-full border">
                  {{ cluster.files.length }} 文件
                </span>
              </div>
              
              <div class="flex items-center gap-2">
                <div class="text-right">
                  <div class="text-sm font-medium text-gray-900">
                    相似度: {{ Math.round(cluster.similarity_score * 100) }}%
                  </div>
                  <div class="text-xs text-gray-500">
                    {{ formatFileSize(cluster.files.reduce((sum, f) => sum + f.size, 0)) }}
                  </div>
                </div>
                
                <svg 
                  class="w-5 h-5 text-gray-400 transition-transform"
                  :class="{ 'rotate-180': cluster.is_expanded }"
                  fill="none" 
                  stroke="currentColor" 
                  viewBox="0 0 24 24"
                >
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
                </svg>
              </div>
            </div>
            
            <!-- 相似度进度条 -->
            <div class="mt-3">
              <div class="w-full bg-gray-200 rounded-full h-2">
                <div 
                  class="h-2 rounded-full transition-all duration-300"
                  :style="{ 
                    width: (cluster.similarity_score * 100) + '%',
                    backgroundColor: getClusterColor(cluster.similarity_score)
                  }"
                ></div>
              </div>
            </div>
          </div>
          
          <!-- 聚类内容 -->
          <div v-if="cluster.is_expanded" class="cluster-content p-4">
            <!-- 中心文件 -->
            <div v-if="cluster.center_file" class="center-file mb-4 p-3 bg-yellow-50 rounded-lg border border-yellow-200">
              <div class="flex items-center gap-3">
                <div class="w-2 h-2 bg-yellow-500 rounded-full"></div>
                <div class="flex-1">
                  <div class="font-medium text-gray-900 text-sm">{{ cluster.center_file.name }}</div>
                  <div class="text-xs text-gray-500">中心文件 • {{ formatFileSize(cluster.center_file.size) }}</div>
                </div>
                <input 
                  type="checkbox" 
                  v-model="cluster.center_file.selected"
                  class="w-4 h-4 text-blue-600 rounded focus:ring-blue-500"
                />
              </div>
            </div>
            
            <!-- 聚类文件列表 -->
            <div class="space-y-2">
              <div 
                v-for="(file, index) in cluster.files.filter(f => f !== cluster.center_file)" 
                :key="file.path"
                class="file-item flex items-center gap-3 p-2 hover:bg-gray-50 rounded-lg transition-colors"
              >
                <div class="w-2 h-2 bg-gray-300 rounded-full"></div>
                <div class="flex-1 min-w-0">
                  <div class="font-medium text-gray-900 text-sm truncate">{{ file.name }}</div>
                  <div class="text-xs text-gray-500 truncate">{{ file.path }}</div>
                </div>
                <div class="text-right flex-shrink-0">
                  <div class="text-xs text-gray-900">{{ formatFileSize(file.size) }}</div>
                </div>
                <input 
                  type="checkbox" 
                  v-model="file.selected"
                  class="w-4 h-4 text-blue-600 rounded focus:ring-blue-500"
                />
              </div>
            </div>
            
            <!-- 聚类操作 -->
            <div class="mt-4 pt-3 border-t border-gray-200">
              <div class="flex items-center justify-between">
                <div class="text-xs text-gray-500">
                  已选择 {{ cluster.files.filter(f => f.selected).length }} / {{ cluster.files.length }} 个文件
                </div>
                <div class="flex gap-2">
                  <button 
                    @click="selectAllInCluster(cluster)"
                    class="px-2 py-1 text-xs bg-blue-500 hover:bg-blue-600 text-white rounded transition-colors"
                  >
                    全选
                  </button>
                  <button 
                    @click="deselectAllInCluster(cluster)"
                    class="px-2 py-1 text-xs bg-gray-500 hover:bg-gray-600 text-white rounded transition-colors"
                  >
                    取消
                  </button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 相似度矩阵热图 -->
    <div v-else-if="viewMode === 'heatmap'" class="heatmap-container">
      <div class="bg-white rounded-lg border border-gray-200 p-6">
        <h4 class="text-lg font-semibold text-gray-900 mb-4">相似度矩阵热图</h4>
        
        <!-- 热图画布 -->
        <div class="heatmap-canvas-container">
          <canvas 
            ref="heatmapCanvas"
            class="border border-gray-300 rounded"
            :width="heatmapSize"
            :height="heatmapSize"
            @mousemove="handleHeatmapHover"
            @mouseleave="hideHeatmapTooltip"
          ></canvas>
          
          <!-- 热图工具提示 -->
          <div 
            v-if="heatmapTooltip.visible"
            class="heatmap-tooltip absolute z-10 bg-black text-white text-xs rounded px-2 py-1 pointer-events-none"
            :style="{ left: heatmapTooltip.x + 'px', top: heatmapTooltip.y + 'px' }"
          >
            {{ heatmapTooltip.text }}
          </div>
        </div>
        
        <!-- 热图图例 -->
        <div class="mt-4 flex items-center justify-center gap-4">
          <div class="flex items-center gap-2">
            <div class="w-4 h-4 bg-blue-100 border"></div>
            <span class="text-xs text-gray-600">低相似度</span>
          </div>
          <div class="w-32 h-2 bg-gradient-to-r from-blue-100 via-yellow-300 to-red-500 rounded"></div>
          <div class="flex items-center gap-2">
            <div class="w-4 h-4 bg-red-500 border"></div>
            <span class="text-xs text-gray-600">高相似度</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, nextTick, watch } from 'vue'
import { invoke } from '@tauri-apps/api/tauri'

interface FileInfo {
  name: string
  path: string
  size: number
  modified: Date
  selected: boolean
}

interface ClusterGroup {
  id: string
  files: FileInfo[]
  similarity_score: number
  center_file?: FileInfo
  is_expanded: boolean
}

interface DuplicateGroup {
  files: FileInfo[]
  size: number
}

interface Props {
  duplicateGroups: DuplicateGroup[]
}

const props = defineProps<Props>()
const emit = defineEmits<{
  'update-groups': [groups: DuplicateGroup[]]
}>()

// 状态管理
const viewMode = ref<'clusters' | 'heatmap'>('clusters')
const similarityThreshold = ref(0.7)
const isLoading = ref(false)
const clusters = ref<ClusterGroup[]>([])

// 热图相关
const heatmapCanvas = ref<HTMLCanvasElement>()
const heatmapSize = 400
const heatmapTooltip = ref({
  visible: false,
  x: 0,
  y: 0,
  text: ''
})

// 计算属性
const filteredClusters = computed(() => {
  return clusters.value.filter(cluster => 
    cluster.similarity_score >= similarityThreshold.value
  )
})

// 方法
const formatFileSize = (bytes: number): string => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

const getClusterColor = (similarity: number): string => {
  // 根据相似度返回颜色
  if (similarity >= 0.9) return '#ef4444' // 红色 - 高相似度
  if (similarity >= 0.7) return '#f59e0b' // 黄色 - 中等相似度
  if (similarity >= 0.5) return '#3b82f6' // 蓝色 - 低相似度
  return '#9ca3af' // 灰色 - 很低相似度
}

const toggleClusterExpansion = (clusterId: string) => {
  const cluster = clusters.value.find(c => c.id === clusterId)
  if (cluster) {
    cluster.is_expanded = !cluster.is_expanded
  }
}

const selectAllInCluster = (cluster: ClusterGroup) => {
  cluster.files.forEach(file => {
    file.selected = true
  })
  emitGroupsUpdate()
}

const deselectAllInCluster = (cluster: ClusterGroup) => {
  cluster.files.forEach(file => {
    file.selected = false
  })
  emitGroupsUpdate()
}

const refreshClusters = async () => {
  isLoading.value = true
  
  try {
    const newClusters = await invoke<ClusterGroup[]>('cluster_similar_files', {
      groups: props.duplicateGroups
    })
    
    clusters.value = newClusters.map(cluster => ({
      ...cluster,
      is_expanded: false
    }))
    
    // 更新热图
    nextTick(() => {
      drawHeatmap()
    })
    
  } catch (error) {
    console.error('聚类失败:', error)
  } finally {
    isLoading.value = false
  }
}

const emitGroupsUpdate = () => {
  // 将聚类数据转换回原始格式
  const updatedGroups = clusters.value.map(cluster => ({
    files: cluster.files,
    size: cluster.files.reduce((sum, f) => sum + f.size, 0)
  }))
  
  emit('update-groups', updatedGroups)
}

// 热图相关方法
const drawHeatmap = () => {
  if (!heatmapCanvas.value) return
  
  const canvas = heatmapCanvas.value
  const ctx = canvas.getContext('2d')
  if (!ctx) return
  
  const clusterCount = clusters.value.length
  if (clusterCount === 0) return
  
  const cellSize = heatmapSize / clusterCount
  
  // 清空画布
  ctx.clearRect(0, 0, heatmapSize, heatmapSize)
  
  // 绘制热图
  for (let i = 0; i < clusterCount; i++) {
    for (let j = 0; j < clusterCount; j++) {
      const similarity = calculateSimilarity(clusters.value[i], clusters.value[j])
      const color = getSimilarityColor(similarity)
      
      ctx.fillStyle = color
      ctx.fillRect(i * cellSize, j * cellSize, cellSize, cellSize)
      
      // 添加边框
      ctx.strokeStyle = '#e5e7eb'
      ctx.lineWidth = 1
      ctx.strokeRect(i * cellSize, j * cellSize, cellSize, cellSize)
    }
  }
}

const calculateSimilarity = (cluster1: ClusterGroup, cluster2: ClusterGroup): number => {
  if (cluster1.id === cluster2.id) return 1.0
  
  // 简化的相似度计算
  // 实际应该基于文件内容、大小、路径等多个因素
  const size1 = cluster1.files.reduce((sum, f) => sum + f.size, 0)
  const size2 = cluster2.files.reduce((sum, f) => sum + f.size, 0)
  
  const sizeDiff = Math.abs(size1 - size2) / Math.max(size1, size2)
  return Math.max(0, 1 - sizeDiff)
}

const getSimilarityColor = (similarity: number): string => {
  // 将相似度映射到颜色
  const r = Math.round(255 * similarity)
  const g = Math.round(255 * (1 - similarity))
  const b = 100
  
  return `rgb(${r}, ${g}, ${b})`
}

const handleHeatmapHover = (event: MouseEvent) => {
  if (!heatmapCanvas.value) return
  
  const canvas = heatmapCanvas.value
  const rect = canvas.getBoundingClientRect()
  const x = event.clientX - rect.left
  const y = event.clientY - rect.top
  
  const clusterCount = clusters.value.length
  if (clusterCount === 0) return
  
  const cellSize = heatmapSize / clusterCount
  const i = Math.floor(x / cellSize)
  const j = Math.floor(y / cellSize)
  
  if (i >= 0 && i < clusterCount && j >= 0 && j < clusterCount) {
    const similarity = calculateSimilarity(clusters.value[i], clusters.value[j])
    
    heatmapTooltip.value = {
      visible: true,
      x: event.clientX + 10,
      y: event.clientY - 30,
      text: `聚类 ${i} ↔ 聚类 ${j}: ${Math.round(similarity * 100)}%`
    }
  }
}

const hideHeatmapTooltip = () => {
  heatmapTooltip.value.visible = false
}

// 生命周期
onMounted(() => {
  refreshClusters()
})

// 监听阈值变化
watch(similarityThreshold, () => {
  nextTick(() => {
    if (viewMode.value === 'heatmap') {
      drawHeatmap()
    }
  })
})

// 监听视图模式变化
watch(viewMode, (newMode) => {
  if (newMode === 'heatmap') {
    nextTick(() => {
      drawHeatmap()
    })
  }
})
</script>

<style scoped>
.similarity-cluster-view {
  height: 100%;
  overflow-y: auto;
}

.cluster-card {
  transition: all 0.2s ease;
}

.cluster-card:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.cluster-header {
  transition: background-color 0.2s ease;
}

.cluster-header:hover {
  background: linear-gradient(to right, #dbeafe, #f3e8ff);
}

.file-item {
  border-left: 2px solid transparent;
  transition: all 0.2s ease;
}

.file-item:hover {
  border-left-color: #3b82f6;
  background-color: #f8fafc;
}

.heatmap-canvas-container {
  position: relative;
  display: inline-block;
}

.heatmap-tooltip {
  transform: translateY(-100%);
  white-space: nowrap;
}

/* 滚动条样式 */
.similarity-cluster-view::-webkit-scrollbar {
  width: 8px;
}

.similarity-cluster-view::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 4px;
}

.similarity-cluster-view::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 4px;
}

.similarity-cluster-view::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

/* 动画 */
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

.cluster-card {
  animation: fadeIn 0.3s ease-out;
}

.cluster-content {
  animation: fadeIn 0.2s ease-out;
}
</style>
